<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
    "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<meta name="generator" content="AsciiDoc 8.5.2" />
<title>Gerrit Code Review - Developer Setup</title>
<style type="text/css">
/* Debug borders */
p, li, dt, dd, div, pre, h1, h2, h3, h4, h5, h6 {
/*
  border: 1px solid red;
*/
}

body {
  margin: 1em 5% 1em 5%;
}

a {
  color: blue;
  text-decoration: underline;
}
a:visited {
  color: fuchsia;
}

em {
  font-style: italic;
  color: navy;
}

strong {
  font-weight: bold;
  color: #083194;
}

tt {
  color: navy;
}

h1, h2, h3, h4, h5, h6 {
  color: #527bbd;
  font-family: sans-serif;
  margin-top: 1.2em;
  margin-bottom: 0.5em;
  line-height: 1.3;
}

h1, h2, h3 {
  border-bottom: 2px solid silver;
}
h2 {
  padding-top: 0.5em;
}
h3 {
  float: left;
}
h3 + * {
  clear: left;
}

div.sectionbody {
  font-family: serif;
  margin-left: 0;
}

hr {
  border: 1px solid silver;
}

p {
  margin-top: 0.5em;
  margin-bottom: 0.5em;
}

ul, ol, li > p {
  margin-top: 0;
}

pre {
  padding: 0;
  margin: 0;
}

span#author {
  color: #527bbd;
  font-family: sans-serif;
  font-weight: bold;
  font-size: 1.1em;
}
span#email {
}
span#revnumber, span#revdate, span#revremark {
  font-family: sans-serif;
}

div#footer {
  font-family: sans-serif;
  font-size: small;
  border-top: 2px solid silver;
  padding-top: 0.5em;
  margin-top: 4.0em;
}
div#footer-text {
  float: left;
  padding-bottom: 0.5em;
}
div#footer-badges {
  float: right;
  padding-bottom: 0.5em;
}

div#preamble {
  margin-top: 1.5em;
  margin-bottom: 1.5em;
}
div.tableblock, div.imageblock, div.exampleblock, div.verseblock,
div.quoteblock, div.literalblock, div.listingblock, div.sidebarblock,
div.admonitionblock {
  margin-top: 1.0em;
  margin-bottom: 1.5em;
}
div.admonitionblock {
  margin-top: 2.0em;
  margin-bottom: 2.0em;
  margin-right: 10%;
  color: #606060;
}

div.content { /* Block element content. */
  padding: 0;
}

/* Block element titles. */
div.title, caption.title {
  color: #527bbd;
  font-family: sans-serif;
  font-weight: bold;
  text-align: left;
  margin-top: 1.0em;
  margin-bottom: 0.5em;
}
div.title + * {
  margin-top: 0;
}

td div.title:first-child {
  margin-top: 0.0em;
}
div.content div.title:first-child {
  margin-top: 0.0em;
}
div.content + div.title {
  margin-top: 0.0em;
}

div.sidebarblock > div.content {
  background: #ffffee;
  border: 1px solid silver;
  padding: 0.5em;
}

div.listingblock > div.content {
  border: 1px solid silver;
  background: #f4f4f4;
  padding: 0.5em;
}

div.quoteblock, div.verseblock {
  padding-left: 1.0em;
  margin-left: 1.0em;
  margin-right: 10%;
  border-left: 5px solid #dddddd;
  color: #777777;
}

div.quoteblock > div.attribution {
  padding-top: 0.5em;
  text-align: right;
}

div.verseblock > div.content {
  white-space: pre;
}
div.verseblock > div.attribution {
  padding-top: 0.75em;
  text-align: left;
}
/* DEPRECATED: Pre version 8.2.7 verse style literal block. */
div.verseblock + div.attribution {
  text-align: left;
}

div.admonitionblock .icon {
  vertical-align: top;
  font-size: 1.1em;
  font-weight: bold;
  text-decoration: underline;
  color: #527bbd;
  padding-right: 0.5em;
}
div.admonitionblock td.content {
  padding-left: 0.5em;
  border-left: 3px solid #dddddd;
}

div.exampleblock > div.content {
  border-left: 3px solid #dddddd;
  padding-left: 0.5em;
}

div.imageblock div.content { padding-left: 0; }
span.image img { border-style: none; }
a.image:visited { color: white; }

dl {
  margin-top: 0.8em;
  margin-bottom: 0.8em;
}
dt {
  margin-top: 0.5em;
  margin-bottom: 0;
  font-style: normal;
  color: navy;
}
dd > *:first-child {
  margin-top: 0.1em;
}

ul, ol {
    list-style-position: outside;
}
ol.arabic {
  list-style-type: decimal;
}
ol.loweralpha {
  list-style-type: lower-alpha;
}
ol.upperalpha {
  list-style-type: upper-alpha;
}
ol.lowerroman {
  list-style-type: lower-roman;
}
ol.upperroman {
  list-style-type: upper-roman;
}

div.compact ul, div.compact ol,
div.compact p, div.compact p,
div.compact div, div.compact div {
  margin-top: 0.1em;
  margin-bottom: 0.1em;
}

div.tableblock > table {
  border: 3px solid #527bbd;
}
thead, p.table.header {
  font-family: sans-serif;
  font-weight: bold;
}
tfoot {
  font-weight: bold;
}
td > div.verse {
  white-space: pre;
}
p.table {
  margin-top: 0;
}
/* Because the table frame attribute is overriden by CSS in most browsers. */
div.tableblock > table[frame="void"] {
  border-style: none;
}
div.tableblock > table[frame="hsides"] {
  border-left-style: none;
  border-right-style: none;
}
div.tableblock > table[frame="vsides"] {
  border-top-style: none;
  border-bottom-style: none;
}


div.hdlist {
  margin-top: 0.8em;
  margin-bottom: 0.8em;
}
div.hdlist tr {
  padding-bottom: 15px;
}
dt.hdlist1.strong, td.hdlist1.strong {
  font-weight: bold;
}
td.hdlist1 {
  vertical-align: top;
  font-style: normal;
  padding-right: 0.8em;
  color: navy;
}
td.hdlist2 {
  vertical-align: top;
}
div.hdlist.compact tr {
  margin: 0;
  padding-bottom: 0;
}

.comment {
  background: yellow;
}

.footnote, .footnoteref {
  font-size: 0.8em;
}

span.footnote, span.footnoteref {
  vertical-align: super;
}

#footnotes {
  margin: 20px 0 20px 0;
  padding: 7px 0 0 0;
}

#footnotes div.footnote {
  margin: 0 0 5px 0;
}

#footnotes hr {
  border: none;
  border-top: 1px solid silver;
  height: 1px;
  text-align: left;
  margin-left: 0;
  width: 20%;
  min-width: 100px;
}


@media print {
  div#footer-badges { display: none; }
}

div#toc {
  margin-bottom: 2.5em;
}

div#toctitle {
  color: #527bbd;
  font-family: sans-serif;
  font-size: 1.1em;
  font-weight: bold;
  margin-top: 1.0em;
  margin-bottom: 0.1em;
}

div.toclevel1, div.toclevel2, div.toclevel3, div.toclevel4 {
  margin-top: 0;
  margin-bottom: 0;
}
div.toclevel2 {
  margin-left: 2em;
  font-size: 0.9em;
}
div.toclevel3 {
  margin-left: 4em;
  font-size: 0.9em;
}
div.toclevel4 {
  margin-left: 6em;
  font-size: 0.9em;
}
/* Workarounds for IE6's broken and incomplete CSS2. */

div.sidebar-content {
  background: #ffffee;
  border: 1px solid silver;
  padding: 0.5em;
}
div.sidebar-title, div.image-title {
  color: #527bbd;
  font-family: sans-serif;
  font-weight: bold;
  margin-top: 0.0em;
  margin-bottom: 0.5em;
}

div.listingblock div.content {
  border: 1px solid silver;
  background: #f4f4f4;
  padding: 0.5em;
}

div.quoteblock-attribution {
  padding-top: 0.5em;
  text-align: right;
}

div.verseblock-content {
  white-space: pre;
}
div.verseblock-attribution {
  padding-top: 0.75em;
  text-align: left;
}

div.exampleblock-content {
  border-left: 3px solid #dddddd;
  padding-left: 0.5em;
}

/* IE6 sets dynamically generated links as visited. */
div#toc a:visited { color: blue; }
</style>
<script type="text/javascript">
/*<![CDATA[*/
window.onload = function(){asciidoc.footnotes(); asciidoc.toc(2);}
var asciidoc = {  // Namespace.

/////////////////////////////////////////////////////////////////////
// Table Of Contents generator
/////////////////////////////////////////////////////////////////////

/* Author: Mihai Bazon, September 2002
 * http://students.infoiasi.ro/~mishoo
 *
 * Table Of Content generator
 * Version: 0.4
 *
 * Feel free to use this script under the terms of the GNU General Public
 * License, as long as you do not remove or alter this notice.
 */

 /* modified by Troy D. Hanson, September 2006. License: GPL */
 /* modified by Stuart Rackham, 2006, 2009. License: GPL */

// toclevels = 1..4.
toc: function (toclevels) {

  function getText(el) {
    var text = "";
    for (var i = el.firstChild; i != null; i = i.nextSibling) {
      if (i.nodeType == 3 /* Node.TEXT_NODE */) // IE doesn't speak constants.
        text += i.data;
      else if (i.firstChild != null)
        text += getText(i);
    }
    return text;
  }

  function TocEntry(el, text, toclevel) {
    this.element = el;
    this.text = text;
    this.toclevel = toclevel;
  }

  function tocEntries(el, toclevels) {
    var result = new Array;
    var re = new RegExp('[hH]([2-'+(toclevels+1)+'])');
    // Function that scans the DOM tree for header elements (the DOM2
    // nodeIterator API would be a better technique but not supported by all
    // browsers).
    var iterate = function (el) {
      for (var i = el.firstChild; i != null; i = i.nextSibling) {
        if (i.nodeType == 1 /* Node.ELEMENT_NODE */) {
          var mo = re.exec(i.tagName);
          if (mo && (i.getAttribute("class") || i.getAttribute("className")) != "float") {
            result[result.length] = new TocEntry(i, getText(i), mo[1]-1);
          }
          iterate(i);
        }
      }
    }
    iterate(el);
    return result;
  }

  var toc = document.getElementById("toc");
  var entries = tocEntries(document.getElementById("content"), toclevels);
  for (var i = 0; i < entries.length; ++i) {
    var entry = entries[i];
    if (entry.element.id == "")
      entry.element.id = "_toc_" + i;
    var a = document.createElement("a");
    a.href = "#" + entry.element.id;
    a.appendChild(document.createTextNode(entry.text));
    var div = document.createElement("div");
    div.appendChild(a);
    div.className = "toclevel" + entry.toclevel;
    toc.appendChild(div);
  }
  if (entries.length == 0)
    toc.parentNode.removeChild(toc);
},


/////////////////////////////////////////////////////////////////////
// Footnotes generator
/////////////////////////////////////////////////////////////////////

/* Based on footnote generation code from:
 * http://www.brandspankingnew.net/archive/2005/07/format_footnote.html
 */

footnotes: function () {
  var cont = document.getElementById("content");
  var noteholder = document.getElementById("footnotes");
  var spans = cont.getElementsByTagName("span");
  var refs = {};
  var n = 0;
  for (i=0; i<spans.length; i++) {
    if (spans[i].className == "footnote") {
      n++;
      // Use [\s\S] in place of . so multi-line matches work.
      // Because JavaScript has no s (dotall) regex flag.
      note = spans[i].innerHTML.match(/\s*\[([\s\S]*)]\s*/)[1];
      noteholder.innerHTML +=
        "<div class='footnote' id='_footnote_" + n + "'>" +
        "<a href='#_footnoteref_" + n + "' title='Return to text'>" +
        n + "</a>. " + note + "</div>";
      spans[i].innerHTML =
        "[<a id='_footnoteref_" + n + "' href='#_footnote_" + n +
        "' title='View footnote' class='footnote'>" + n + "</a>]";
      var id =spans[i].getAttribute("id");
      if (id != null) refs["#"+id] = n;
    }
  }
  if (n == 0)
    noteholder.parentNode.removeChild(noteholder);
  else {
    // Process footnoterefs.
    for (i=0; i<spans.length; i++) {
      if (spans[i].className == "footnoteref") {
        var href = spans[i].getElementsByTagName("a")[0].getAttribute("href");
        href = href.match(/#.*/)[0];  // Because IE return full URL.
        n = refs[href];
        spans[i].innerHTML =
          "[<a href='#_footnote_" + n +
          "' title='View footnote' class='footnote'>" + n + "</a>]";
      }
    }
  }
}

}
/*]]>*/
</script>
</head>
<body>
<div id="header">
<h1>Gerrit Code Review - Developer Setup</h1>
<span id="revnumber">version 2.3</span>
<div id="toc">
  <div id="toctitle">Table of Contents</div>
  <noscript><p><b>JavaScript must be enabled in your browser to display the table of contents.</b></p></noscript>
</div>
</div>
<div id="content">
<div id="preamble">
<div class="sectionbody">
<div class="paragraph"><p>Apache Maven is needed to compile the code, and a SQL database
to house the review metadata.  H2 is recommended for development
databases, as it requires no external server process.</p></div>
</div>
</div>
<h2 id="_get_the_source">Get the Source</h2>
<div class="sectionbody">
<div class="paragraph"><p>Create a new client workspace:</p></div>
<div class="listingblock">
<div class="content">
<pre><tt>  git clone https://gerrit.googlesource.com/gerrit
  cd gerrit</tt></pre>
</div></div>
</div>
<h2 id="_configuring_eclipse">Configuring Eclipse</h2>
<div class="sectionbody">
<div class="paragraph"><p>To use the Eclipse IDE for development, please see
<a href="dev-eclipse.html">Eclipse Setup</a> for more details on how to
configure the workspace with the Maven build scripts.</p></div>
</div>
<h2 id="build">Building</h2>
<div class="sectionbody">
<div class="paragraph"><p>From the command line:</p></div>
<div class="listingblock">
<div class="content">
<pre><tt>  mvn package</tt></pre>
</div></div>
<div class="paragraph"><p>Output executable WAR will be placed in:</p></div>
<div class="listingblock">
<div class="content">
<pre><tt>  gerrit-war/target/gerrit-*.war</tt></pre>
</div></div>
<h3 id="_mac_os_x">Mac OS X</h3><div style="clear:left"></div>
<div class="paragraph"><p>On Mac OS X ensure "Java For Mac OS X 10.5 Upate 4" (or later) has
been installed, and that <tt>JAVA_HOME</tt> is set to
"/System/Library/Frameworks/JavaVM.framework/Versions/1.6/Home".
Check the installed version by running <tt>java -version</tt> and looking
for <em>build 1.6.0_13-b03-211</em>.  Versions of Java 6 prior to this
version crash during the build due to a bug in the JIT compiler.</p></div>
</div>
<h2 id="init">Site Initialization</h2>
<div class="sectionbody">
<div class="paragraph"><p>After compiling (above), run Gerrit&#8217;s <em>init</em> command to create a
testing site for development use:</p></div>
<div class="listingblock">
<div class="content">
<pre><tt>  java -jar gerrit-war/target/gerrit-*.war init -d ../test_site</tt></pre>
</div></div>
<div class="paragraph"><p>Accept defaults by pressing Enter until <em>init</em> completes, or add
the <em>--batch</em> command line option to avoid them entirely.  It is
recommended to change the listen addresses from <em>*</em> to <em>localhost</em> to
prevent outside connections from contacting the development instance.</p></div>
<div class="paragraph"><p>The daemon will automatically start in the background and a web
browser will launch to the start page, enabling login via OpenID.</p></div>
<div class="paragraph"><p>Shutdown the daemon after registering the administrator account
through the web interface:</p></div>
<div class="listingblock">
<div class="content">
<pre><tt>  ../test_site/bin/gerrit.sh stop</tt></pre>
</div></div>
</div>
<h2 id="_testing">Testing</h2>
<div class="sectionbody">
<h3 id="_running_the_daemon">Running the Daemon</h3><div style="clear:left"></div>
<div class="paragraph"><p>The daemon can be directly launched from the build area, without
copying to the test site:</p></div>
<div class="listingblock">
<div class="content">
<pre><tt>  java -jar gerrit-war/target/gerrit-*.war daemon -d ../test_site</tt></pre>
</div></div>
<h3 id="_querying_the_database">Querying the Database</h3><div style="clear:left"></div>
<div class="paragraph"><p>The embedded H2 database can be queried and updated from the
command line.  If the daemon is not currently running:</p></div>
<div class="listingblock">
<div class="content">
<pre><tt>  java -jar gerrit-war/target/gerrit-*.war gsql -d ../test_site</tt></pre>
</div></div>
<div class="paragraph"><p>Or, if it is running and the database is in use, connect over SSH
using an administrator user account:</p></div>
<div class="listingblock">
<div class="content">
<pre><tt>  ssh -p 29418 user@localhost gerrit gsql</tt></pre>
</div></div>
<h3 id="_debugging_javascript">Debugging JavaScript</h3><div style="clear:left"></div>
<div class="paragraph"><p>When debugging browser specific issues use <tt>-Dgwt.style=DETAILED</tt>
so the resulting JavaScript more closely matches the Java sources.
This can be used to help narrow down what code line 30,400 in the
JavaScript happens to be.</p></div>
<div class="listingblock">
<div class="content">
<pre><tt>  mvn package -Dgwt.style=DETAILED</tt></pre>
</div></div>
</div>
<h2 id="_release_builds">Release Builds</h2>
<div class="sectionbody">
<div class="paragraph"><p>To create a release build for a production server, or deployment
through the download site:</p></div>
<div class="listingblock">
<div class="content">
<pre><tt>  ./tools/release.sh</tt></pre>
</div></div>
<div class="paragraph"><p>If AsciiDoc isn&#8217;t installed or is otherwise unavailable, the WAR
can still be built without the embedded documentation by passing
an additional flag:</p></div>
<div class="listingblock">
<div class="content">
<pre><tt>  ./tools/release.sh --without-documentation</tt></pre>
</div></div>
</div>
<h2 id="_client_server_rpc">Client-Server RPC</h2>
<div class="sectionbody">
<div class="paragraph"><p>The client-server RPC implementation is gwtjsonrpc, not the stock RPC
system that comes with GWT.  This buys us automatic XSRF protection.
It also makes all of the messages readable and writable by any JSON
implementation, facilitating "mashups" and 3rd party clients.</p></div>
<div class="paragraph"><p>The programming API is virtually identical, except service interfaces
extend RemoteJsonService instead of RemoteService.</p></div>
</div>
<h2 id="_why_gwt">Why GWT?</h2>
<div class="sectionbody">
<div class="paragraph"><p>We like it.  Plus we can write Java code once and run it both in
the browser and on the server side.</p></div>
</div>
<h2 id="_external_links">External Links</h2>
<div class="sectionbody">
<div class="paragraph"><p>Google Web Toolkit:</p></div>
<div class="ulist"><ul>
<li>
<p>
<a href="http://code.google.com/webtoolkit/download.html">Download</a>
</p>
</li>
</ul></div>
<div class="paragraph"><p>Apache Maven:</p></div>
<div class="ulist"><ul>
<li>
<p>
<a href="http://maven.apache.org/download.html">Download</a>
</p>
</li>
<li>
<p>
<a href="http://maven.apache.org/run-maven/index.html">Running</a>
</p>
</li>
</ul></div>
<div class="paragraph"><p>Apache SSHD:</p></div>
<div class="ulist"><ul>
<li>
<p>
<a href="http://mina.apache.org/sshd/">SSHD</a>
</p>
</li>
</ul></div>
<div class="paragraph"><p>H2:</p></div>
<div class="ulist"><ul>
<li>
<p>
<a href="http://www.h2database.com/">H2</a>
</p>
</li>
<li>
<p>
<a href="http://www.h2database.com/html/grammar.html">SQL Reference</a>
</p>
</li>
</ul></div>
<div class="paragraph"><p>PostgreSQL:</p></div>
<div class="ulist"><ul>
<li>
<p>
<a href="http://www.postgresql.org/download/">Download</a>
</p>
</li>
<li>
<p>
<a href="http://www.postgresql.org/docs/">Documentation</a>
</p>
</li>
</ul></div>
</div>
<hr style="
  height: 2px;
  color: silver;
  margin-top: 1.2em;
  margin-bottom: 0.5em;
">
<div class="paragraph"><p>Part of <a href="index.html">Gerrit Code Review</a></p></div>
</div>
<div id="footnotes"><hr /></div>
<div id="footer">
<div id="footer-text">
Version 2.3<br />
Last updated 2012-03-07 11:57:26 MDT
</div>
</div>
</body>
</html>
